import java.util.Date;
import java.util.HashMap;

import com.nullprogram.chess.Game;
import com.nullprogram.chess.GameEvent;
import com.nullprogram.chess.GameListener;
import com.nullprogram.chess.Piece.Side;
import com.nullprogram.chess.ai.AlphaBeta;
import com.nullprogram.chess.boards.StandardBoard;
import com.nullprogram.chess.pieces.Bishop;
import com.nullprogram.chess.pieces.King;
import com.nullprogram.chess.pieces.Knight;
import com.nullprogram.chess.pieces.Pawn;
import com.nullprogram.chess.pieces.Queen;
import com.nullprogram.chess.pieces.Rook;


public class CompetitionDriver implements GameListener{

	int numGames;
	int depth;
	AlphaBeta white;
	AlphaBeta black;
	HashMap<Class, Double> whitePV;
	HashMap<Class, Double> blackPV;
	
	/*
	 * Archbishop value: 6.0000000000000000
	Rook value: 0.4787644172221509
	King value: 0.7433820628518222
	Knight value: 0.9097343731189159
	Bishop value: 0.8312498030041695
	Chancellor value: 8.5000000000000000
	Pawn value: 0.3979899133390970
	Queen value: 0.7083296871409470
	 */
	double WHITE_PAWN    = 1;
	double WHITE_QUEEN   = 9;
	double WHITE_BISHOP  = 3;
	double WHITE_KNIGHT  = 3;
	double WHITE_KING    = 1000;
	double WHITE_ROOK    = 5;
	
	double BLACK_PAWN    = 1;
	double BLACK_QUEEN   = 9.32;
	double BLACK_BISHOP  = 3.18;
	double BLACK_KNIGHT  = 2.29;
	double BLACK_KING    = 1000;
	double BLACK_ROOK    = 5.2;
	
	int whiteWinCount = 0;
	int blackWinCount = 0;
	
	public static void main(String[] args) {
		CompetitionDriver cd = new CompetitionDriver();
		cd.numGames = 500;
		cd.depth   = 3;
		try {
			cd.runExperiment();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void runExperiment() throws InterruptedException {
		whitePV = buildPieceValues(Side.WHITE);
		blackPV = buildPieceValues(Side.BLACK);

		for (int i = 0; i < numGames; i++) {
			System.out.println("Game " + i);
			StandardBoard board = new StandardBoard();
			Game game = new Game(board);
			white = new AlphaBeta(game);
			white.setMaxDepth(depth);
			white.setPieceValues(whitePV);
			black = new AlphaBeta(game);
			black.setMaxDepth(depth);
			black.setPieceValues(blackPV);
			game.seat(white, black);
			game.addGameListener(this);
			game.begin();
			Date start = new Date();
			Thread.sleep(1000);
			while (!game.isDone()) {
				// limit game time
				if (new Date().getTime() - start.getTime() > 30000) {
					game.end();
				}
				Thread.sleep(1000);
			}
		}
		
		System.out.println("White Wins: "+whiteWinCount);
		System.out.println("Black Wins: "+blackWinCount);
		System.out.println("White is white, black is black");

	}

	@Override
	public void gameEvent(GameEvent event) {
		if(event.getGame().isDone()){
			if(event.getGame().getWinner() == Side.WHITE){
				whiteWinCount++;
			}else if(event.getGame().getWinner() == Side.BLACK){
				blackWinCount++;
			}
		}
		
	}
	
	private HashMap<Class,Double> buildPieceValues(Side s){
		HashMap<Class,Double> pv = new HashMap<Class,Double>();
		if(s == Side.WHITE){
			pv.put(Pawn.class, WHITE_PAWN);
			pv.put(Queen.class, WHITE_QUEEN);
			pv.put(King.class, WHITE_KING);
			pv.put(Bishop.class, WHITE_BISHOP);
			pv.put(Knight.class, WHITE_KNIGHT);
			pv.put(Rook.class, WHITE_ROOK);
		}else{
			pv.put(Pawn.class, BLACK_PAWN);
			pv.put(Queen.class, BLACK_QUEEN);
			pv.put(King.class, BLACK_KING);
			pv.put(Bishop.class, BLACK_BISHOP);
			pv.put(Knight.class, BLACK_KNIGHT);
			pv.put(Rook.class, BLACK_ROOK);
		}
		return pv;
	}

}
